/*****************************************************************************
 *
 * Copyright (c), 2004-2020,ShangHai Neotune Information Technology Co., Ltd.
 *
 * Module Name : buffer.h
 *
 * Author :    sean
 *
 * Date :    2004-02-05
 *
 * Version :    1.00
 *
 * Description :    
 *
 * Other :    
 *
 * Data Structure List: <Main Data Structure>
 *
 * Modification History
 * ---------------------------------------------------------------------------
 *  1: Data :      2004-02-05
 *    Author :     sean
 *    Version :    V100R001M00
 *    Modification : creation
 *
*****************************************************************************/


#if (!defined(buffer_inc))
#define buffer_inc

#ifdef __cplusplus
extern"C" {
#endif

#if (!defined(asn1_inc))
#include <asn1.h>
#endif

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 1
#endif

/* The EBUFFER_T structure is used to control encoding into a buffer    */
typedef struct EBUFFER_S
        {
        unsigned int bflags;
        bits8_t     *start_bp;  /* Start of the buffer.                     */
        bits8_t     *next_bp;   /* Next location in buffer to be filled     */
        ALENGTH_T    remaining; /* Number of empty spots remaining in buffer*/
        } EBUFFER_T;

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 0
#endif

/* Values for bflags    */
#define BFL_IS_ALLOC            0x0002  /* Buffer must be obtained */
#define BFL_IS_DYNAMIC          0x0001  /* Buffer was obtained by malloc    */
#define BFL_IS_STATIC           0x0000  /* Buffer is statically allocated   */

/****************************************************************************

NAME:  EBufferInitialize

PURPOSE:  Initialize a buffer to a know, but not usable state
          EBufferSetup must be used to make the buffer ready for use.

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    Nothing

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferInitialize(E) (((EBUFFER_T *)(E))->bflags=0,   \
                              ((EBUFFER_T *)(E))->next_bp=(bits8_t *)0,  \
                              ((EBUFFER_T *)(E))->start_bp=(bits8_t *)0,  \
                              ((EBUFFER_T *)(E))->remaining=(ALENGTH_T)0)

/****************************************************************************

NAME:  EBufferSetup

PURPOSE:  Setup a buffer to receive ASN.1 encoded data

PARAMETERS:
            unsigned int    BFL_xxx flags from buffer.h
            EBUFFER_T *     Buffer descriptor
            bits8_t *       Address of the buffer
            ALENGTH_T       Length of the buffer

RETURNS:    Nothing

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferSetup(F,E,B,L) (((EBUFFER_T *)(E))->bflags=(F),  \
                               ((EBUFFER_T *)(E))->start_bp=(bits8_t *)(B),  \
                               ((EBUFFER_T *)(E))->next_bp=(bits8_t *)(B),  \
                               ((EBUFFER_T *)(E))->remaining=(ALENGTH_T)(L))

/****************************************************************************

NAME:  EBufferPreLoad

PURPOSE:  Pre-load data into a buffer

PARAMETERS:
            unsigned int    BFL_xxx flags from buffer.h
            EBUFFER_T *     Buffer descriptor
            bits8_t *       Address of the buffer containing the data
            ALENGTH_T       Length of the data

RETURNS:    Nothing

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferPreLoad(F,E,B,L) (       \
        ((EBUFFER_T *)(E))->bflags=(F), \
        ((EBUFFER_T *)(E))->start_bp=(bits8_t *)(B),    \
        ((EBUFFER_T *)(E))->next_bp=((bits8_t *)(B)+(ALENGTH_T)(L)),    \
        ((EBUFFER_T *)(E))->remaining=(ALENGTH_T)0)

/****************************************************************************

NAME:  EBufferNext

PURPOSE:  Obtain address of next free byte in a buffer

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    bits8_t *       Buffer descriptor

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferNext(E)  (((EBUFFER_T *)(E))->next_bp)

/****************************************************************************

NAME:  EBufferStart

PURPOSE:  Obtain address of first byte in a buffer

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    bits8_t *       Buffer descriptor

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferStart(E) (((EBUFFER_T *)(E))->start_bp)

/****************************************************************************

NAME:  EBufferUsed

PURPOSE:  Indicate how many octets are currently in the buffer.

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    ALENGTH_T       Number of octets used.

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferUsed(E)  ((ALENGTH_T)((((EBUFFER_T *)(E))->next_bp) -    \
                                     (((EBUFFER_T *)(E))->start_bp)))

/****************************************************************************

NAME:  EBufferRemaining

PURPOSE:  Indicate how many octets are currently unused in the buffer.

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    ALENGTH_T       Number of octets unused.

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferRemaining(E)     (((EBUFFER_T *)(E))->remaining)

/****************************************************************************

NAME:  EBufferReset

PURPOSE:  Reset the buffer to an empty state, just like after EBufferSetup

PARAMETERS:
            EBUFFER_T *     Buffer descriptor

RETURNS:    Nothing

RESTRICTIONS:  

BUGS:  
****************************************************************************/
#define EBufferReset(E) ( \
                         (((EBUFFER_T *)(E))->remaining += \
                          ((EBUFFER_T *)(E))->next_bp - \
                          ((EBUFFER_T *)(E))->start_bp), \
                         ((void)(((EBUFFER_T *)(E))->next_bp =  \
                                 ((EBUFFER_T *)(E))->start_bp)))

extern  int     EBufferClone   __((EBUFFER_T *, EBUFFER_T *));
extern  int    EBufferClean   __((EBUFFER_T *));
extern  void    EBufferAppend  __((EBUFFER_T *, EBUFFER_T *));
extern  int     EBufferSeek    __((EBUFFER_T *, ALENGTH_T, int));
extern  int     EBufferAdjust  __((EBUFFER_T *, ALENGTH_T));
extern  int     EBufferReplace __((EBUFFER_T *, bits8_t *, ALENGTH_T));
extern  int     EBufferAllocateLoad __((unsigned int, EBUFFER_T *,
                                        bits8_t *, ALENGTH_T));

#ifdef __cplusplus
}
#endif

#endif  /* buffer_inc */
